package org.extframework.ld.service.pojo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.extframework.ld.bean.Power;
import org.extframework.ld.bean.Role;
import org.extframework.ld.bean.User;
import org.extframework.ld.conf.PowerType;
import org.extframework.ld.content.XmlContent;
import org.extframework.ld.content.model.XmlMenuNode;
import org.extframework.ld.service.PowerManager;
import org.extframework.ld.service.SysManager;
import org.extframework.ld.sort.XmlMenuSort;
import org.extframework.ld.util.StringUtils;
import org.extframework.ld.xml.ExtPageXmlControl;
import org.extframework.ld.xml.base.RightMenu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author : Dong.Li
 * @created : 2013-1-21
 * @version : 1.0
 * @description :
 */
public class DefaultPowerManager extends DefaultBaseManager implements
		PowerManager {

	@Autowired
	private SysManager sysManager;
	
	@Autowired
	private ExtPageXmlControl pageXmlControl;

	@Transactional
	public List<Power> getPowersByUserId(Long id) {
		return getPowersByUserId(id, null);
	}

	@Transactional
	public void refreshMenu() {

		List<XmlMenuNode> menuNodeList = new ArrayList<XmlMenuNode>();
		List<RightMenu> rightMenusList = new ArrayList<RightMenu>();

		XmlMenuNode[] menuNodes = XmlContent.getRootNodes();
		Map<String, RightMenu> map = ExtPageXmlControl.getRightMenuMap();

		for (XmlMenuNode menuNode : menuNodes) {

			menuNodeList.add(menuNode);
			if (XmlContent.getNode(menuNode.getId()) == null)
				continue;
			for (XmlMenuNode xmn : XmlContent.getNode(menuNode.getId())
					.getChiledMenuNodes()) {
				XmlMenuNode node = new XmlMenuNode();
				node.setParentMenuNode(menuNode);
				node.setId(xmn.getId());
				node.setText(xmn.getText());
				node.setLeaf(xmn.isLeaf());
				node.setSort(xmn.getSort());
				node.setIconCls(xmn.getIconCls());
				menuNodeList.add(node);
			}
		}

		for (Entry<String, RightMenu> entries : map.entrySet()) {
			rightMenusList.add(entries.getValue());
		}

		refreshMenu(menuNodeList, rightMenusList);
	}

	@Transactional
	public void refreshMenu(List<XmlMenuNode> menuNodes,
			List<RightMenu> rightMenus) {

		String hql = "FROM Power p WHERE p.type = :type";

		List<XmlMenuNode> tempMenuNodes = new ArrayList<XmlMenuNode>();
		List<Power> menuPowers = commDao.findByQuery(hql, "type",
				PowerType.MENU);
		List<RightMenu> tempRightMenus = new ArrayList<RightMenu>();
		List<Power> rightPowers = commDao.findByQuery(hql, "type",
				PowerType.RIGHT);

		// 刷新 菜单

		for (XmlMenuNode menuNode : menuNodes) {
			for (Power power : menuPowers) {
				if (menuNode.getId().equals(power.getPowerId())) {
					power.setName(menuNode.getText());
					tempMenuNodes.add(menuNode);
				} else if (menuNode.getParentMenuNode() != null) {
					if (menuNode.getParentMenuNode().getId()
							.equals(power.getPowerId())) {

					}
				}
			}
		}

		menuNodes.removeAll(tempMenuNodes);

		for (XmlMenuNode menuNode : menuNodes) {
			addPower(menuNode.getText(), PowerType.MENU,
					menuNode.getParentMenuNode() != null ? menuNode
							.getParentMenuNode().getId() : null,
					menuNode.getId());
		}

		// 刷新右键菜单

		for (RightMenu menu : rightMenus) {
			for (Power power : rightPowers) {
				if (menu.getMid().equals(power.getPowerId())) {
					power.setName(menu.getText());
					tempRightMenus.add(menu);
				}
			}
		}

		rightMenus.removeAll(tempRightMenus);

		for (RightMenu menu : rightMenus) {
			addPower(menu.getText(), PowerType.RIGHT, null, menu.getMid());
		}
	}

	@Transactional
	public String getPowerToArrayStr(Long userId) {

		return null;
	}

	@Transactional
	public List<Power> getPowersByUserId(Long id, String treeId) {

		User user = commDao.load(User.class, id);
		Set<Role> roles = user.getRoles();
		Set<Power> powers = new HashSet<Power>();

		if (treeId != null) {

			for (Role re : roles) {
				if (re.getBeActive()) {
					Set<Power> ps = re.getPowers();
					for (Power p : ps) {
						if (p.getBeActive()) {
							if (p.getPower() != null
									&& p.getPower().getPowerId().equals(treeId))
								powers.add(p);
						}
					}
				}
			}

		} else {

			for (Role re : roles) {
				if (re.getBeActive()) {
					Set<Power> ps = re.getPowers();
					for (Power p : ps) {
						if (p.getBeActive()) {
							powers.add(p);
						}
					}
				}
			}

		}
		return new ArrayList<Power>(powers);
	}

	@Transactional
	public void addPower(Power power) {
		commDao.store(power);
	}

	@Transactional
	public void addPower(String name, String type, String parentId,
			String powerId) {
		// System.out.println("name :" +name+ "type :" + type+ "parentId :" +
		// parentId+"powerId :" + powerId);
		Power power = null;
		if (!(StringUtils.isEmpty(parentId) || parentId
				.equals("$NONE-IS-MENU$"))) {
			power = commDao.load(Power.class, Long.parseLong(parentId));
		}
		addPower(new Power(type, powerId, name, power));
	}

	@Transactional
	public Set<Power> getPowerIdsByRole(Long role) {
		Role role2 = commDao.load(Role.class, role);
		Set<Power> powers = role2.getPowers();
		for (Power power : powers) {
			power = commDao.load(Power.class, power.getId());
		}
		return powers;
	}

	@Transactional
	public Map<String, List<Object[]>> getRoleAll(int start, int end,
			String query) {

		String hql;
		if (StringUtils.isEmpty(query)) {
			hql = "SELECT r.id,r.name FROM Role r WHERE 1=1 ORDER BY r.id";
		} else {
			hql = "SELECT r.id,r.name FROM Role r WHERE r.name like '" + query
					+ "%' ORDER BY r.id";
		}
		return sysManager.getObjects(hql, start, end, new Object[0]);
	}
	
	public String get(Power power ,String stringBuffer,
			Map<String,Power> powerMaps,Map<Long,Power> parentPowerMaps){
		
		Power oldPower = power;
		
		while( parentPowerMaps.containsKey(power.getId()) ){//判断是否还有子节点
			
			power = parentPowerMaps.get(power.getId());
			
			System.out.println("\t 子节点"+power.getName()+"开始解析");
			if(stringBuffer.indexOf("#childNodes#") >-1){
				
				if( parentPowerMaps.containsKey(power.getId()) ){
					System.out.println("\t "+power.getName()+"还有子节点");
					stringBuffer = stringBuffer.replaceFirst("#childNodes#", ",childNodes:["+ String.format(
							"{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false #childNodes# } #childNode# ]",
										power.getId(),power.getName()));
				}else{
					System.out.println("\t "+power.getName()+"是最终节点");
					stringBuffer = stringBuffer.replaceFirst("#childNodes#", ",childNodes:["+ String.format(
							"{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:true } #childNode# ]",
										power.getId(),power.getName()));
					
					power = oldPower;
				}
				
			}else{
				
				if( parentPowerMaps.containsKey(power.getId()) ){
					System.out.println("\t 子节点"+power.getName()+"开始解析");
					stringBuffer = stringBuffer.replaceFirst("#childNode#", ","+ String.format(
							"{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false #childNodes# } #childNode# ",
												power.getId(),power.getName()));
				}else{
					System.out.println("\t "+power.getName()+"是最终节点");
					stringBuffer = stringBuffer.replaceFirst("#childNode#", ","+ String.format(
							"{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:true} #childNode# ",
												power.getId(),power.getName()));
					power = oldPower;
				}
				
			}
		}
		return stringBuffer;
	}
	
	@SuppressWarnings("unchecked")
	@Transactional
	public String getRPowerAllToJson( Long powerId ,Long roleId ){
		
		Power power = commDao.load(Power.class, powerId);
		
		Role role = null;
		if(! (roleId == null)){
			System.out.println(roleId+"   ========================");
			role = commDao.load(Role.class, roleId);
		}
		
		StringBuffer stringBuffer = new StringBuffer();
		
		//查出权限下所有的子权限
		
		List<Power> powers1 = commDao.findByQuery(" SELECT p FROM Power p " +
				"LEFT JOIN p.power parentPower WHERE parentPower.id =:parentPowerId AND p.type='RIGHT'","parentPowerId",power.getId());
		
		if(powers1.size() == 0){
			return null;
		}
		
		for(Power power1 : powers1){
			
			
			if( !isLeaf(power1) ){//还有子节点
				
				stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:"+isChecked(role, power1)+",leaf:false ,childNodes:[ ",power1.getId(), power1.getName()));
				
				List<Power> powers2 = commDao.findByQuery(" SELECT p FROM Power p " +
						"LEFT JOIN p.power parentPower WHERE parentPower.id =:parentPowerId AND p.type='RIGHT'","parentPowerId",power1.getId());
				
				for(Power power2 : powers2){
					stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:"+isChecked(role, power2)+",leaf:true},",power2.getId(), power2.getName()));
				}
				
				stringBuffer.append("]},");
			}else{
				stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:"+isChecked(role, power1)+",leaf:true},",power1.getId(), power1.getName()));
			}
			
		}
		
		return stringBuffer.toString().substring(0, stringBuffer.length()-1).replaceAll(",\\]", "]");
	}
	
	@Transactional
	public Boolean isChecked( Role role,Power power ){
		if(role == null){
			return false;
		}
		
		return role.getPowers().contains(power);
	}
	
	@Transactional
	private Boolean isLeaf(Power p){
		return commDao.findByQuery(" SELECT p FROM Power p " +
				"LEFT JOIN p.power parentPower WHERE parentPower.id =:parentPowerId AND p.type='RIGHT'","parentPowerId",p.getId()).size()==0;
	}

	@Transactional
	public String getPowerAllToJson() {
		
		List<Power> powers = commDao.loadAll(Power.class);
		Map<String,Power> powerMaps = new HashMap<String,Power>();
		StringBuffer stringBuffer = new StringBuffer();
		
		for(Power power : powers){
			powerMaps.put(power.getPowerId(), power);
		}
		
		List<XmlMenuNode> rootNodes = new ArrayList<XmlMenuNode>();
		for(XmlMenuNode xmn : XmlContent.getRootNodes()){
			rootNodes.add(xmn);
		}
		Collections.sort(rootNodes, new XmlMenuSort());
		
		//获取根节点
		for (XmlMenuNode xmn : rootNodes) {
			
			if( powerMaps.containsKey(xmn.getId()) ){
				Power power = powerMaps.get(xmn.getId());
				System.out.println("开始解析根目录:"+power.getName());
				
				if( !xmn.isLeaf() ){//判断是否还有子节点
					
					stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false ,childNodes:[ ",power.getId(), power.getName()));
					System.out.println("解析结果:"+stringBuffer.toString());
					System.out.println(power.getName()+"还有子节点");
					
					List<XmlMenuNode> menuNodes1 = XmlContent.getNode(xmn.getId()).getChiledMenuNodes();
					Collections.sort(menuNodes1, new XmlMenuSort());
					
					for(XmlMenuNode menuNode1 : menuNodes1){
						Power power1 = powerMaps.get(menuNode1.getId());
						System.out.println("\t开始解析["+power1.getName()+"]"+menuNode1.getText());
						if( !menuNode1.isLeaf() ){
							
							System.out.println("\t"+power.getName()+"还有子节点");
							stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false ,childNodes:[ ",power1.getId(), power1.getName()));
							
							List<XmlMenuNode> menuNodes2 = XmlContent.getNode(menuNode1.getId()).getChiledMenuNodes();
							Collections.sort(menuNodes2, new XmlMenuSort());
							
							for(XmlMenuNode menuNode2 : menuNodes2){
								Power power2 = powerMaps.get(menuNode2.getId());
								System.out.println("\t开始解析["+power2.getName()+"]"+menuNode2.getText());
								if( !menuNode2.isLeaf() ){
//									
									System.out.println("\t"+power2.getName()+"还有子节点");
									stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false ,childNodes:[ ",power2.getId(), power2.getName()));
									
									List<XmlMenuNode> menuNodes3 = XmlContent.getNode(menuNode2.getId()).getChiledMenuNodes();
									Collections.sort(menuNodes3, new XmlMenuSort());
									
									for(XmlMenuNode menuNode3 : menuNodes3){
										Power power3 = powerMaps.get(menuNode3.getId());
										System.out.println("\t开始解析["+power3.getName()+"]"+menuNode3.getText());
										stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:false},",power3.getId(), power3.getName()));
									}
//									
								}else{
//									
									System.out.println("\t"+power2.getName()+"最终节点");
									stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:true},",power2.getId(), power2.getName()));
//									
								}
//							
//								
							}
							stringBuffer.append("]},");
						}else{
							
							System.out.println("\t"+power1.getName()+"最终节点");
							stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:true},",power1.getId(), power1.getName()));
							
						}
					}
					
					stringBuffer.append("]},");
					System.out.println("当前进度解析结果:"+stringBuffer.toString());
				}else{
					
					System.out.println(power.getName()+"是最终节点");
					stringBuffer.append(String.format("{id:'%d',text:'%s',allowDrag:false,checked:false,leaf:true},",power.getId(), power.getName()));
					
				}
				
			}
			
		}
		
		powerMaps.clear();
		
		System.out.println("最终结果:"+stringBuffer.toString());
		return stringBuffer.toString().substring(0, stringBuffer.length()-1).replaceAll(",\\]", "]");
		
	}
	
	@Transactional
	public void storeRP(Long roleId, String powersIds,String rPowersIds) {
		
		Role role = commDao.load(Role.class, roleId);
		
		//删除角色所有MENU权限
		role.getPowers().removeAll(commDao.findByQuery(" SELECT p FROM Power p " +
				"WHERE p.type = 'MENU'"));
		
		if(!StringUtils.isEmpty(powersIds)){
			
			
			//重新授权
			String[] ids = powersIds.split(",");
			
			role = commDao.load(Role.class, roleId);
			for( String idStr : ids ){
				
				String[] str = idStr.split("\\|");
				Power power1 = commDao.load(Power.class, Long.parseLong(str[0]));
				
				if(Boolean.valueOf(str[1])){
					role.getPowers().add(power1);
				}else{
					role.getPowers().remove(power1);
				}
				
			}
		}
		
		
		//右键权限
		if(!StringUtils.isEmpty(rPowersIds)){
			String[] rIds = rPowersIds.split(",");
			Power power = commDao.load(Power.class, Long.parseLong(rIds[0].split("\\|")[0]));
			role.getPowers().removeAll(commDao.findByQuery("SELECT p FROM Power p " +
					"LEFT JOIN p.power parentPower WHERE p.type ='RIGHT' AND parentPower.id =:parentPowerId "
						,"parentPowerId",power.getPower().getId()));
			
			//重新授权
			for( String idStr : rIds ){
				String[] ids = idStr.split("\\|");
				Power power1 = commDao.load(Power.class, Long.parseLong(ids[0]));
				if(Boolean.valueOf(ids[1])){
					role.getPowers().add(power1);
				}
			}
		}
		
	}
	
	@SuppressWarnings("unchecked")
	@Transactional
	public String rPowers(Long roleId, Long powerId) {
		
		StringBuffer buffer = new StringBuffer();
		List<Power> powers = commDao.findByQuery("SELECT p FROM Power p " +
				"LEFT JOIN p.power parentPower " +
				"WHERE p.type = 'RIGHT' AND parentPower.id =:parentPowerId ","parentPowerId",powerId);
		
		if(powers.size() == 0){
			return null;
		}
		
		Role role = null;
		if( roleId != null ){
			role = commDao.load(Role.class, roleId);
		}
		
		for(Power power : powers){
			buffer.append(String.format("{boxLabel:'%s',id:'%s',checked:"+(roleId != null && role.getPowers().contains(power))+"},", 
					power.getName(),power.getId()));
		}
		return buffer.toString().substring(0, buffer.length()-1);
	}

}
